package edu.nf.relaxenjoy.web.task;

import com.alibaba.fastjson.JSON;
import edu.nf.relaxenjoy.common.constant.platform.PlatformConstant;
import edu.nf.relaxenjoy.common.util.ConvertUtils;
import edu.nf.relaxenjoy.common.util.JsonUtils;
import edu.nf.relaxenjoy.common.util.RedisUtils;
import edu.nf.relaxenjoy.domain.entity.Album;
import edu.nf.relaxenjoy.domain.entity.Comment;
import edu.nf.relaxenjoy.domain.entity.Post;
import edu.nf.relaxenjoy.domain.entity.User;
import edu.nf.relaxenjoy.domain.state.AlbumState;
import edu.nf.relaxenjoy.domain.state.CommentState;
import edu.nf.relaxenjoy.domain.state.PostState;
import edu.nf.relaxenjoy.domain.state.UserState;
import edu.nf.relaxenjoy.domain.vo.PostVo;
import edu.nf.relaxenjoy.mapper.AlbumMapper;
import edu.nf.relaxenjoy.mapper.CommentMapper;
import edu.nf.relaxenjoy.mapper.PostMapper;
import edu.nf.relaxenjoy.mapper.UserMapper;
import edu.nf.relaxenjoy.service.AlbumService;
import edu.nf.relaxenjoy.service.CommentService;
import edu.nf.relaxenjoy.service.PostService;
import edu.nf.relaxenjoy.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author zhu
 * @date 2024-12-24
 */
@Component
@EnableScheduling
@EnableAsync
@RequiredArgsConstructor
public class PlatformTask {

    private final RedisUtils redisUtils;

    private final PostMapper postMapper;

    private final CommentMapper commentMapper;

    private final AlbumMapper albumMapper;

    private final UserMapper userMapper;

    @Async
    @Scheduled(fixedDelay = 1000 * 60)  //间隔1分
    public void updateImgDetail() {

        Set<String> listKey = redisUtils.getListKey(PlatformConstant.POST_STATE);
        if (!listKey.isEmpty()) {
            for (String k : listKey) {
                String mid = k.split(":")[1];
                Post post = postMapper.getById(Long.valueOf(mid));
                String postStateKey = PlatformConstant.POST_STATE + mid;
                PostState postState = JsonUtils.parseObject(redisUtils.get(postStateKey), PostState.class);
                post.setViewCount(postState.getViewCount());
                post.setAgreeCount(postState.getAgreeCount());
                post.setCommentCount(postState.getCommentCount());
                post.setCollectionCount(postState.getCollectionCount());
                postMapper.updateById(post);
            }
        }
    }

    @Async
    @Scheduled(fixedDelay = 1000 * 60)  //间隔1分
    public void updateComment() {

        Set<String> listKey = redisUtils.getListKey(PlatformConstant.COMMENT_STATE);
        if (!listKey.isEmpty()) {
            for (String k : listKey) {
                String cid = k.split(":")[1];
                Comment comment = commentMapper.getById(Long.valueOf(cid));
                String commonStateKey = PlatformConstant.COMMENT_STATE + cid;
                CommentState commentState = JsonUtils.parseObject(redisUtils.get(commonStateKey), CommentState.class);
                comment.setTwoNums(commentState.getTwoNums());
                comment.setCount(commentState.getCount());
                commentMapper.updateById(comment);
            }
        }
    }

    @Async
    @Scheduled(fixedDelay = 1000 * 60)  //间隔1分
    public void updateUser() {

        Set<String> listKey = redisUtils.getListKey(PlatformConstant.USER_STATE);
        if (!listKey.isEmpty()) {
            for (String k : listKey) {
                String uid = k.split(":")[1];
                User user = userMapper.getUserByUserId(Long.valueOf(uid));
                String userStateKey = PlatformConstant.USER_STATE + uid;
                UserState userState = JsonUtils.parseObject(redisUtils.get(userStateKey), UserState.class);
                user.setTrendCount(userState.getTrendCount());
                user.setFollowCount(userState.getFollowCount());
                user.setFanCount(userState.getFanCount());

                userMapper.updateById(user);
            }
        }
    }

    @Async
    @Scheduled(fixedDelay = 1000 * 60)  //间隔1分
    public void updateAlbum() {

        Set<String> listKey = redisUtils.getListKey(PlatformConstant.ALBUM_STATE);
        if (!listKey.isEmpty()) {
            for (String k : listKey) {
                String aid = k.split(":")[1];
                Album album = albumMapper.getById(Long.valueOf(aid));
                String albumStateKey = PlatformConstant.ALBUM_STATE + aid;
                AlbumState albumState = JsonUtils.parseObject(redisUtils.get(albumStateKey), AlbumState.class);
                album.setCollectionCount(albumState.getCollectionCount());
                albumMapper.updateById(album);
            }
        }
    }


    @Async
    @Scheduled(fixedDelay = 1000 * 60 * 10)  //10分钟刷新一次热榜
    public void refreshHot() {

        List<Post> postList = postMapper.getHotList(1);
        List<PostVo> list = new ArrayList<>();

        List<Long> uids = postList.stream().map(Post::getUserId).collect(Collectors.toList());
        List<User> userList = new ArrayList<>();
        if (!uids.isEmpty()) {
            userList = userMapper.listByIds(uids);
        }

        HashMap<Long, User> userMap = new HashMap<>();
        userList.forEach(item -> {
            userMap.put(item.getId(), item);
        });

        PostVo postVo;
        List<String> imgList;
        User userEntity;
        for (Post model : postList) {
            imgList = JSON.parseArray(model.getImages().replace("\\\"", "\""), String.class);
            userEntity = userMap.get(model.getUserId());
            postVo = ConvertUtils.sourceToTarget(model, PostVo.class);
            postVo.setImages(imgList);
            postVo.setUsername(userEntity.getUsername());
            postVo.setAvatar(userEntity.getAvatar());
            list.add(postVo);
        }

        redisUtils.set(PlatformConstant.HOT, JSON.toJSONString(list));
    }
}
